/**
 * @author Nicolas Zimerman (zimerman@usi.ch)
 * @author Isabella Nake (isabella.nake@usi.ch)
 * @author Nicolas Lusa (lusan@usi.ch)
 * @author Nicolas Latorre (nicolas.latorre@usi.ch)
 */
package ch.usi.inf.pf2.circuit;

import java.awt.Font;
import java.awt.Graphics;
import java.util.ArrayList;

import javax.swing.JLabel;

import ch.usi.inf.pf2.time.Event;
import ch.usi.inf.pf2.time.Eventable;

public final class Input extends Component implements Eventable {
	private static final long serialVersionUID = -583751759215741388L;
	private OutputPin outputPin;
	private ArrayList<Wire> wires;
	private String waveform;
	private String name;
	private JLabel label;
	
	private int x1;
    private int y1;
    
    private int x2;
    private int y2;
    
    private int x3;
    private int y3;
    
    private int x4;
    private int y4;
    
    private String color;
	
	public Input(final int x, final int y) {
		outputPin = new OutputPin();
		wires = new ArrayList<Wire>();
		
		this.x1 = x;
        this.y1 = y;
        
        this.x2 = x1 + 15;
        this.y2 = y1;
        
        this.x3 = x1;
        this.y3 = y1 + 15;
        
        this.x4 = x1 + 15;
        this.y4 = y1 + 15;
        
        color = "black";
        waveform = "";
        
        label = new JLabel();
	}
	
	//MODEL PART
	
	public void execute(final Event ev) {
		this.setValue(ev.getValue());
	}
	
	public void setValue(final Value value) {
		outputPin.setValue(value);
		if(value == Value.TRUE) {
			color = "green";
		} else if(value == Value.FALSE) {
			color = "blue";
		} else {
			color = "black";
		}
	}
	
	public Value getValue() { 
		return outputPin.getValue();
	}

	public void setWire(final Wire wire) {
		this.wires.add(wire);
		this.outputPin.addWire(wire);
		wire.setOutputPin(outputPin);
	}
	
	public void setWaveform(final String waveform) {
		this.waveform = waveform;
	}
	
	public String getWaveform() {
		return waveform;
	}
	
	@Override
	public Wire[] getWires() {
		Wire[] w = new Wire[wires.size()];
		for(int i = 0; i < wires.size(); i++) {
			w[i] = wires.get(i);
		}
		return w;
	}
	
	//GUI PART
	
	public int getOriginX() {
	    return x2;
	}		 
	 
	public int getOriginY() {
	    return (y2 + y4)/2;
	}
	
	public void draw(final Graphics g) {
		g.drawLine(x1, y1, x2, y2);
		g.drawLine(x1, y1, x3, y3);
		g.drawLine(x3, y3, x4, y4);
		g.drawLine(x2, y2, x4, y4);		
		g.setFont(new Font("TimesRoman", Font.PLAIN, 12));
		g.drawString(name, x1 - g.getFontMetrics().stringWidth(name) - 5, getOriginY() + g.getFontMetrics().getMaxAscent()/2);
	}
	
	public boolean contains(final int x, final int y) {
	    return x>=x1 && x<=x2 && y>=y1 && y<=y3;
	}

	@Override
	public void move(final int deltaX, final int deltaY) {
		x1 += deltaX;
		x2 += deltaX;
		x3 += deltaX;
		x4 += deltaX;
		
		y1 += deltaY;
		y2 += deltaY;
		y3 += deltaY;
		y4 += deltaY;
		
		if(wires != null) {
			for(Wire wire: wires) {
				wire.moveXY1(deltaX, deltaY);
			}
		}
		
	}
	
	public String getColor() {
		return color;
	}
	
	public void setName(final String name) {
		this.name = name;
	}
	
	public String getName() {
		return name;
	}
	
	public JLabel getLabel() {
		return label;
	}

	public void setLabel() {
		label = new JLabel(name + ": " + waveform);
	}
	
	public String toString() {
	    return "Input: " + getName();
	}
}
